iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
Modern Web

JS30 x 鐵人30 x MDN doc系列 第 27

[Day27] - Click and Drag(JS30 x 鐵人 30 x MDN)

  • 分享至 

  • xImage
  •  

做一個區塊可以讓使用者左右拖曳顯示的項目

突然發覺後面幾天好像都只是結合前面學習的組合技,或是以另一種方式呈現而已,所使用到的 Web API 及操作都大同小異,想到拖曳功能立馬聯想到 Day11 客製化影片播放器的影片進度條拖曳功能,有一句名言叫做不要「重造輪子」,因此我決定拿前面的程式碼過來進行改寫。

  1. 一樣是拖曳必須是在滑鼠按下狀態移動滑鼠才會觸發,所以這裡需要用到相當多的事件監聽器。
//  先宣告一個變數存放上次的滑鼠X座標
let lastX = 0;
//  取得包含所有item的容器節點
const div = document.querySelector(".items");

//  滑鼠按下時才新增 滑鼠移動的事件監聽器以及新增active class
slider.addEventListener("mousedown", handleMouseDown);

function handleMouseDown(e) {
  //  每次觸發後複寫現在觸發的X值,供 mousemove handler計算使用
  lastX = e.clientX;
  slider.classList.add("active");
  slider.addEventListener("mousemove", handleDrag);
}

//  滑鼠彈起 及 滑鼠離開progressContainer容器則會將滑鼠移動的監聽器移除,以及移除active class
slider.addEventListener("mouseup", removeListener);
slider.addEventListener("mouseleave", removeListener);

function removeListener(params) {
  slider.removeEventListener("mousemove", handleDrag);
  slider.classList.remove("active");
}

與作者使用狀態切換去判斷要不要滾動不同的是,我改用mousedown時才會新增mousemove的事件監聽器,滑鼠彈起或離開容器時則會再將這個mousemove的事件監聽器移除,這樣會相對節省一些效能

  1. 最後就是最重要的事件處理函式handleDrag: 將父層容器的左邊滾動偏移量加上上次鼠標位置減去現在觸發位置,有可能是負值(上次 X 值為:100 往往右滑 X 值:120 滑動),等於 scrollLeft-20,這邊需要反向思考,如有不懂可使用 console.log()印出來方便理解。
function handleDrag(e) {
  slider.scrollLeft += lastX - e.clientX;
  //  最後再將這次的X值賦值回去給下一次事件觸發使用
  lastX = e.clientX;
}

👉Github Demo 頁面 👈

👉 好想工作室 15th 鐵人賽看板 👈

參考資料

  1. Javascript 30 官網
    https://javascript30.com/
  2. MDN 官網
    https://developer.mozilla.org/en-US/
  3. 自己的 JS30 Day11
    https://hackmd.io/w9WhJC9cQYKFmAXc_EpmEw?view

上一篇
[Day26] - Stripe Follow Along Nav(JS30 x 鐵人 30 x MDN)
下一篇
[Day28] - Video Speed Controller(JS30 x 鐵人 30 x MDN)
系列文
JS30 x 鐵人30 x MDN doc30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言